package com.ybfenpan.servlet;

import org.springframework.web.util.HtmlUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * XSS攻击过滤拦截器（添加在web.xml中拦截器的前面，如果添加了UTF8编码转换，则在转换下面）
 * 将特殊字符转义接收，如果采用富文本显示特殊字符，显示前需要调用HtmlUtils.htmlUnescape()进行反转义
 * 例如：
 * Notice notice = noticeService.getByKey(id);
 * notice.setContent(HtmlUtils.htmlUnescape(notice.getContent()));
 * request.setAttribute("notice", notice);
 * <p>
 * 转义效果：
 * <script> =》 &lt;script&gt
 * <p>
 * 引入方式：
 * <filter>
 * <filter-name>Xss</filter-name>
 * <filter-class>qukuaijd.servlet.XssFilter</filter-class>
 * </filter>
 * <filter-mapping>
 * <filter-name>Xss</filter-name>
 * <url-pattern>*.shtml</url-pattern>
 * </filter-mapping>
 * Created by lzx on 2017/7/20.
 */
public class XssFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
            @Override
            public String getParameter(String name) {
                return HtmlUtils.htmlEscape(super.getParameter(name));
            }

            @Override
            public Map<String, String[]> getParameterMap() {
                Map<String, String[]> temp = new HashMap<>(super.getParameterMap());
                for (Map.Entry<String, String[]> entry : temp.entrySet()) {
                    entry.setValue(htmlEscape(entry.getValue()));
                }
                return temp;
            }

            private String[] htmlEscape(String[] args) {
                for (int i = 0; i < args.length; i++) {
                    args[i] = HtmlUtils.htmlEscape(args[i]);
                }
                return args;
            }

        }, response);
    }

    @Override
    public void destroy() {
    }

}
